package com.neouton.crm.cm.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.neouton.common.entity.ActivitiVO;
import com.neouton.common.entity.FeeMainVO;
import com.neouton.common.util.*;
import com.neouton.crm.approval.entity.ApprovalVO;
import com.neouton.crm.approval.service.IApprovalService;
import com.neouton.crm.cm.entity.SalesCostMigrateVO;
import com.neouton.crm.cm.mapper.SalesCostMigrateBackMapper;
import com.neouton.crm.cm.mapper.SalesCostMigrateMapper;
import com.neouton.crm.cm.service.CostMigrateService;
import com.neouton.crm.dictionary.entity.DictionaryLookupItemVO;
import com.neouton.crm.dictionary.service.IDictionaryService;
import com.neouton.crm.entity.SysUserEntity;
import com.neouton.crm.op.entity.SalesOpportunityVO;
import com.neouton.crm.op.mapper.SalesOpportunityMapper;
import com.neouton.crm.pm.entity.SalesProjectManageVO;
import com.neouton.crm.pm.mapper.PurchaseOrdeMapper;
import com.neouton.crm.pm.mapper.SalesProjectManageMapper;
import com.neouton.crm.sales.entity.SalesAuditVO;
import com.neouton.crm.sales.mapper.SalesAuditBackMapper;
import com.neouton.crm.sales.mapper.SalesAuditMapper;
import com.neouton.crm.transpondEmail.service.TranspondEmailService;
import com.neouton.feginClient.FeginService;
import com.neouton.feginClient.ReimburseService;
import com.neouton.feginClient.WorkFlowFeginService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author TheSail
 * @date 2023/01/11 17:20:22
 * @description
 */
@Service
public class CostMigrateServiceImpl implements CostMigrateService {
    @Resource
    private WorkFlowFeginService workFlowService;
    @Resource
    private SalesCostMigrateMapper costMigrateMapper;
    @Resource
    private SalesOpportunityMapper salesOpportunityMapper;
    @Resource
    private SalesAuditMapper auditMapper;
    @Resource
    private SalesProjectManageMapper projectManageMapper;
    @Resource
    private FeginService feginService;
    @Resource
    private IDictionaryService dictionaryService;
    @Resource
    private IApprovalService approvalService;
    @Resource
    private SalesCostMigrateBackMapper costMigrateBackMapper;
    @Resource
    private SalesAuditBackMapper auditBackMapper;
    @Resource
    private ReimburseService reimburseService;
    @Resource
    private PurchaseOrdeMapper purchaseOrdeMapper;
    @Resource
    private TranspondEmailService transpondEmailService;

    @Value("${webSit.web}")
    private String webSitUrl;

    @Override
    public PageUtil<SalesCostMigrateVO> queryCostInfo(IPage<SalesCostMigrateVO> page, SalesCostMigrateVO costMigrateVO, List<SysUserEntity> userList, String token) {
        if (costMigrateVO.getOrderByProp() != null) {
            costMigrateVO.setOrderByProp(StringUtils.camelToUnderline(costMigrateVO.getOrderByProp()));
        }
        IPage<SalesCostMigrateVO> iPage = costMigrateMapper.queryCostInfo(page, costMigrateVO, userList);
        List<SalesCostMigrateVO> list = iPage.getRecords();
        if (list != null && !list.isEmpty()) {
            List<SalesCostMigrateVO> voList = costMigrateMapper.queryCostInfo(costMigrateVO, userList);
            BigDecimal amountPage = new BigDecimal(0);
            BigDecimal amountTotal = new BigDecimal(0);
            for (SalesCostMigrateVO item : list) {
                amountPage = amountPage.add(new BigDecimal(item.getAmount().getValue()));
            }
            for (SalesCostMigrateVO item : voList) {
                amountTotal = amountTotal.add(new BigDecimal(item.getAmount().getValue()));
            }
            list.get(0).setAmountPage(String.valueOf(amountPage));
            list.get(0).setAmountTotal(String.valueOf(amountTotal));
            iPage.setRecords(list);
        }
        return new PageUtil<>(iPage);
    }

    @Override
    public PageUtil<SalesCostMigrateVO> queryCostInfoAudit(IPage<SalesCostMigrateVO> page, SalesCostMigrateVO costMigrateVO, List<SysUserEntity> userList, String token) {
        if (costMigrateVO.getOrderByProp() != null) {
            costMigrateVO.setOrderByProp(StringUtils.camelToUnderline(costMigrateVO.getOrderByProp()));
        }
        IPage<SalesCostMigrateVO> iPage = costMigrateMapper.queryCostInfoAudit(page, costMigrateVO);
//        List<SalesCostMigrateVO> list = iPage.getRecords();
//        if (list != null && !list.isEmpty()) {
//            List<SalesCostMigrateVO> voList = costMigrateMapper.queryCostInfo(costMigrateVO, userList);
//            BigDecimal amountPage = new BigDecimal(0);
//            BigDecimal amountTotal = new BigDecimal(0);
//            for (SalesCostMigrateVO item:list) {
//                amountPage = amountPage.add(new BigDecimal(item.getAmount().getValue()));
//            }
//            for (SalesCostMigrateVO item:voList) {
//                amountTotal = amountTotal.add(new BigDecimal(item.getAmount().getValue()));
//            }
//            list.get(0).setAmountPage(String.valueOf(amountPage));
//            list.get(0).setAmountTotal(String.valueOf(amountTotal));
//            iPage.setRecords(list);
//        }
        return new PageUtil<>(iPage);
    }

    @Override
    public SalesCostMigrateVO queryCostInfoById(Integer costMigrateId) {
        SalesCostMigrateVO costMigrateVO = costMigrateMapper.selectByPrimaryKey(Long.valueOf(costMigrateId));
        costMigrateVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(costMigrateVO.getBusinessId()));
        return costMigrateVO;
    }

    @Override
    public List<SalesCostMigrateVO> queryCostById(SalesCostMigrateVO costMigrateVO) {
        List<SalesCostMigrateVO> list = costMigrateMapper.queryCostById(costMigrateVO);
        return list;
    }

    /**
     * 先查该项目的审批记录
     * 取机会id，再查所有的费用记录
     *
     * @param projectManageId
     * @return
     */
    @Override
    public List<SalesCostMigrateVO> queryCostByPM(Integer projectManageId) {
        List<SalesAuditVO> auditVOS = auditMapper.queryOpInfoByPM(projectManageId);
        List<Integer> arrayList = new ArrayList();
        for (SalesAuditVO audit : auditVOS) {
            arrayList.add(audit.getSalesRelationId());
        }
        return costMigrateMapper.queryCostByPM(arrayList);
    }

    @Override
    public List<SalesProjectManageVO> queryProjects(SalesProjectManageVO projectManageVO, String token) {
        List<SysUserEntity> userList = feginService.getUserIgnoreFlag(token).getResult();
        return projectManageMapper.queryProject(projectManageVO, userList);
    }

    public ActivitiVO toWorkFlow(SysUserEntity user, String token) {
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(user.getAccount());
        activitiVO.setProcessName("费用记录审批流程");
        activitiVO.setProcessCode("cost_record_approval");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("leader", user.getAccount());
        activitiVO.setCustomParams(paramMap);
        ActivitiVO workFlowResult = workFlowService.startProcessByDesignCodeVersionBatchCustomParams(activitiVO).getResult();
        return workFlowResult;
    }

    public ActivitiVO toWorkFlows(SysUserEntity user, String token) {
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(user.getAccount());
        activitiVO.setProcessName("费用迁移审批流程");
        activitiVO.setProcessCode("cost_migrate_approval");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("leader", user.getAccount());
        activitiVO.setCustomParams(paramMap);
        ActivitiVO workFlowResult = workFlowService.startProcessByDesignCodeVersionBatchCustomParams(activitiVO).getResult();
        return workFlowResult;
    }

    public String getCostCopyEmails(SalesCostMigrateVO costMigrateVO, String token, List<SysUserEntity> userList) {
        String copyFor = "";        // 抄送人
        Integer principal = costMigrateVO.getPrincipal();       //负责人
        Integer applicant = costMigrateVO.getLastUpdateBy();       //申请人
        if (costMigrateVO.getCopyFor() != null) {
            copyFor = costMigrateVO.getCopyFor();
        }
        StringBuilder copyForUserEmails = new StringBuilder();           // 抄送人邮箱
        if (copyFor != null && copyFor.length() > 0) {
            String[] userIds = copyFor.split(",");          // 获取所有抄送人ID
            List<SysUserEntity> copyForUsers = new ArrayList<>();
            for (String userId : userIds) {         // 根据抄送人ID过滤抄送用户对象
                userList.forEach(userInfo -> {
                    if (userInfo.getUserId() == Integer.parseInt(userId) || userInfo.getUserId().equals(principal)) {
                        copyForUsers.add(userInfo);
                    }
                });
            }
            if (!copyForUsers.isEmpty()) {      // 根据抄送用户对象拼接抄送人邮箱
                for (SysUserEntity copyForUser : copyForUsers) {
                    copyForUserEmails.append(copyForUser.getEmail()).append(",");
                }
                // 移除最后一个逗号
                copyForUserEmails.replace(copyForUserEmails.lastIndexOf(","), copyForUserEmails.length() - 1, "");
            }
        } else {
            for (SysUserEntity userInfo : userList) {
                if (userInfo.getUserId().equals(principal) || userInfo.getUserId().equals(applicant)) {
                    return userInfo.getEmail();
                }
            }
        }
        return copyForUserEmails.toString();
    }

    public String getCostCopyEmail(List<SysUserEntity> userList) {
        StringBuilder copyForUserEmails = new StringBuilder();           // 抄送人邮箱
        if (!userList.isEmpty()) {      // 根据抄送用户对象拼接抄送人邮箱
            for (SysUserEntity copyForUser : userList) {
                copyForUserEmails.append(copyForUser.getEmail()).append(",");
            }
            // 移除最后一个逗号
            copyForUserEmails.replace(copyForUserEmails.lastIndexOf(","), copyForUserEmails.length(), "");
        }
        return copyForUserEmails.toString();
    }

    public void commitCost(SalesCostMigrateVO costMigrateVO, String token) {
        Integer userId = AuthUtils.getUserId();
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(costMigrateVO.getOpportunityId());
        //获取人员信息
        List<SysUserEntity> userList = feginService.getUserIgnoreFlag(token).getResult();
        SysUserEntity user = new SysUserEntity();
        for (SysUserEntity users : userList) {
            if (Objects.equals(users.getUserId(), opportunityVO.getOwner())) {
                user = users;
                break;
            }
        }
        if (Objects.equals(AuthUtils.getUserId(), opportunityVO.getOwner())) {
            //费用和机会所有者相同免审
            ApprovalVO approval = approvalService.initApprovalAndLog(0, Constants.COSTRECORD_TASK_TYPE,
                    costMigrateVO.getReasonApplication(), "", -1, "免审");
            costMigrateVO.setBusinessId(approval.getApprovalId());
            //传工作流或审批表主键
            approvalService.insertApprovalLog(costMigrateVO.getBusinessId(), "通过", "系统判定跳过", costMigrateVO.getProcessComments());
            approvalService.approved(null, costMigrateVO.getBusinessId());
            if (costMigrateVO.getCostMigrateId() == null) {
                costMigrateMapper.insert(costMigrateVO);
            } else {
                costMigrateBackMapper.insertBackInfo(costMigrateVO.getCostMigrateId());
                costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
            }
            // 转发人记录
            if (costMigrateVO.getSenderList() != null && !costMigrateVO.getSenderList().isEmpty()) {
                transpondEmailService.insertTranspondEmailInfoByUser(approval.getApprovalId(), costMigrateVO.getSenderList());
            }
        } else {
            //启动工作流
            ActivitiVO workFlowResult = toWorkFlow(user, token);
            ApprovalVO approval = approvalService.initApprovalAndLog(workFlowResult.getBusinessId(), Constants.COSTRECORD_TASK_TYPE,
                    costMigrateVO.getReasonApplication(), "", user.getUserId(), "");
            costMigrateVO.setBusinessId(approval.getApprovalId());
            String costNumber = "";
            if (costMigrateVO.getCostMigrateId() == null) {
                costMigrateMapper.insert(costMigrateVO);
                costNumber = costMigrateMapper.selectByPrimaryKey(Long.valueOf(costMigrateVO.getCostMigrateId())).getCostNumber();
            } else {
                costMigrateBackMapper.insertBackInfo(costMigrateVO.getCostMigrateId());
                costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
                costNumber = costMigrateMapper.selectByPrimaryKey(Long.valueOf(costMigrateVO.getCostMigrateId())).getCostNumber();
            }
            costMigrateVO.setCostNumber(costNumber);
            // 转发人记录
            if (costMigrateVO.getSenderList() != null && !costMigrateVO.getSenderList().isEmpty()) {
                transpondEmailService.insertTranspondEmailInfoByUser(approval.getApprovalId(), costMigrateVO.getSenderList());
            }
//            List<SysUserEntity> userIList = dictionaryService.queryCcUserIdsByCode("costRecord");
            // 获取机会状态字典
//            String stateDictCode = "costType";
//            List<String> dictCodes = new ArrayList<>();
//            dictCodes.add(stateDictCode);
//            Map<String, List<DictionaryLookupItemVO>> listMap = dictionaryService.queryDictionaryLookupInfo(1, dictCodes);
//            JSONObject userObject = feginService.getUserInfo(token);
//            String copyForUserEmails = getCostCopyEmail(userIList);
            //发送邮件
//            String titel = "【系统通知】费用记录 - 流程单审批通知";
//            String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
//                    "<div><p style='text-indent: 2em'>您好，您有一个新的费用记录审批需要处理：</p></div>" +
//                    "<div><p style='text-indent: 2em'>费用单号：" + costNumber + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>机会名称：" + opportunityVO.getOpportunityTheme() + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>费用类型：" + getCRMDictionaryNameByCode("costType",listMap).get(costMigrateVO.getCostType().toString()) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请人：" + getUserNameById(userObject).get(userId) + " / " + getUserAccountById(userObject).get(userId) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请原因：" + (costMigrateVO.getReasonApplication() == null ? "无" : costMigrateVO.getReasonApplication()  ) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 "+
//                    "<a href='"+webSitUrl+"/?m=crm&p=crmtodoItems&me=todoApprovalPath'>进入</a></p></div>"+
//                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
//                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
            SysUserEntity finalUser = user;
//            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), null, titel, msg, token));
            //调用通知接口
            Timestamp now = new Timestamp(System.currentTimeMillis());
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(costMigrateVO.getBusinessId(), now, userId, 0, Constants.COSTRECORD_TASK_TYPE, finalUser.getUserId(), token));
        }
    }


    @Override
    public void addCost(SalesCostMigrateVO costMigrateVO) {
        costMigrateMapper.insert(costMigrateVO);
    }

    @Override
    public void updateCost(SalesCostMigrateVO costMigrateVO) {
        costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
    }

    @Override
    public void costMigrateAudit(SalesAuditVO auditVO, String token) {
        Integer userId = AuthUtils.getUserId();
        List<SalesAuditVO> salesAuditVO = auditMapper.queryAuditInfo(auditVO.getSalesRelationId(), Constants.COST_MODEL_ID);
        auditVO.setAuditClass(Constants.COST_MODEL_ID);
        SalesProjectManageVO projectManageVO = projectManageMapper.selectByPrimaryKey(auditVO.getSalesMigrateId());
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
        //获取人员信息
        List<SysUserEntity> userList = feginService.getUserIgnoreFlag(token).getResult();
        SysUserEntity user = new SysUserEntity();
        for (SysUserEntity users : userList) {
            if (Objects.equals(users.getUserId(), projectManageVO.getProjectPrincipal())) {
                user = users;
                break;
            }
        }
        if (Objects.equals(AuthUtils.getUserId(), projectManageVO.getProjectPrincipal())) {
            //迁移和项目负责人相同免审
            //报销迁移
            FeeMainVO vo = new FeeMainVO();
            vo.setChanceId(auditVO.getSalesRelationId());
            vo.setProjectId(auditVO.getSalesMigrateId());
            reimburseService.updateProjectIdByChanceId(vo, token);
            ApprovalVO approval = approvalService.initApprovalAndLog(0, Constants.COSTMIGRATE_TASK_TYPE,
                    auditVO.getReasonApplication(), "", -1, "免审");
            auditVO.setBusinessId(approval.getApprovalId());
            //传工作流或审批表主键
            approvalService.insertApprovalLog(auditVO.getBusinessId(), "通过", "系统判定跳过", auditVO.getProcessComments());
            approvalService.approved(null, auditVO.getBusinessId());
            //费用迁移成功，更改费用记录信息
            SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
            costMigrateVO.setOpportunityId(auditVO.getSalesRelationId());
            costMigrateVO.setProjectManageId(auditVO.getSalesMigrateId());
            costMigrateVO.setMigrateState(1);
            costMigrateMapper.updateCostOfProject(costMigrateVO);
            //费用迁移，更改机会点迁移状态 已迁移
            opportunityVO.setMigrateState(1);
        } else {
            //启动工作流
            ActivitiVO workFlowResult = toWorkFlows(user, token);
            ApprovalVO approval = approvalService.initApprovalAndLog(workFlowResult.getBusinessId(), Constants.COSTMIGRATE_TASK_TYPE,
                    auditVO.getReasonApplication(), "", user.getUserId(), "");
            auditVO.setBusinessId(approval.getApprovalId());
//            JSONObject userObject = feginService.getUserInfo(token);
            //发送邮件
//            String titel = "【系统通知】费用迁移 - 流程单审批通知";
//            String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
//                    "<div><p style='text-indent: 2em'>您好，您有来自机会点的费用迁移审批需要处理：</p></div>" +
//                    "<div><p style='text-indent: 2em'>机会单号：" + opportunityVO.getOpportunityNumber() + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>机会名称：" + opportunityVO.getOpportunityTheme() + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>项目名称：" + projectManageVO.getProjectTheme() + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请人：" + getUserNameById(userObject).get(userId) + " / " + getUserAccountById(userObject).get(userId) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>申请原因：" + (auditVO.getReasonApplication() == null ? "无" : auditVO.getReasonApplication()) + "</p></div>" +
//                    "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 " +
//                    "<a href='" + webSitUrl + "/?m=crm&p=todoItems&me=todoApproval'>进入</a></p></div>" +
//                    "<div><p style='text-indent: 2em'>谢谢！</p></div>" +
//                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
            SysUserEntity finalUser = user;
//            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), null, titel, msg, token));
            //调用通知接口
            Timestamp now = new Timestamp(System.currentTimeMillis());
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), now, userId, 0, Constants.COSTMIGRATE_TASK_TYPE, finalUser.getUserId(), token));
            //费用迁移，更改机会点迁移状态 迁移中
            opportunityVO.setMigrateState(2);
        }
        if (salesAuditVO == null || salesAuditVO.isEmpty()) {
            auditMapper.insert(auditVO);
        } else {
            auditBackMapper.insertBackInfo(auditVO.getSalesRelationId(), Constants.COST_MODEL_ID);
            auditMapper.updateByPrimaryKeySelective(auditVO);
        }
        // 转发人记录
        if (auditVO.getSenderList() != null && !auditVO.getSenderList().isEmpty()) {
            transpondEmailService.insertTranspondEmailInfoByUser(auditVO.getBusinessId(), auditVO.getSenderList());
        }
        salesOpportunityMapper.updateByPrimaryKeySelective(opportunityVO);
    }

    @Override
    public Boolean approveCostInfo(SalesCostMigrateVO costMigrateVO, String token) {
//        List<SysUserEntity> userIList = feginService.getUserIgnoreFlag(token).getResult();
        List<SysUserEntity> userIList = dictionaryService.queryCcUserIdsByCode("costRecord");
        String copyForUserEmails = getCostCopyEmail(userIList);
        String transpondEmails = transpondEmailService.selectTranspondEmailStr(costMigrateVO.getBusinessId());
        if (!transpondEmails.isEmpty()) {
            copyForUserEmails = copyForUserEmails + "," + transpondEmails;
        }
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(costMigrateVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        workFlowService.approvalProcessByBusinessId(activitiVO);
        //发送邮件
        SysUserEntity user = feginService.searchUserInfoByIds(costMigrateVO.getPrincipal(), token).getResult();
        String titel = "【系统通知】费用记录 - 流程单审批通过通知";
        String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，您申请的费用记录审批已经通过：</p></div>" +
                "<div><p style='text-indent: 2em'>费用单号：" + costMigrateVO.getCostNumber() + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
                "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 机会信息管理 - 费用信息 " +
                "<a href='" + webSitUrl + "/?m=crm&p=salesManage&me=costMigrate'>进入</a></p></div>" +
                "<div><p style='text-indent: 2em'>谢谢！</p></div>" +
                "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        String finalCopyForUserEmails = copyForUserEmails;
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(user.getEmail(), finalCopyForUserEmails, titel, msg, token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(costMigrateVO.getBusinessId(), costMigrateVO.getLastUpdateTime(), costMigrateVO.getPrincipal(), 1, Constants.COSTRECORD_TASK_TYPE, 0, token));
//        costMigrateVO.setAuditState(2);
        costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
        //传工作流或审批表主键
        approvalService.insertApprovalLog(costMigrateVO.getBusinessId(), "通过", "费用记录审批", costMigrateVO.getProcessComments());
        return approvalService.approved(null, costMigrateVO.getBusinessId());
    }

    @Override
    public Boolean rejectionCostInfo(SalesCostMigrateVO costMigrateVO, String token) {
//        List<SysUserEntity> userIList = feginService.getUserIgnoreFlag(token).getResult();
//        List<SysUserEntity> userIList = dictionaryService.queryCcUserIdsByCode("costRecord");
//        String copyForUserEmails = getCostCopyEmail(userIList);
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(costMigrateVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        workFlowService.approvalProcessByBusinessId(activitiVO);
        //发送邮件
        SysUserEntity user = feginService.searchUserInfoByIds(costMigrateVO.getPrincipal(), token).getResult();
        String titel = "【系统通知】费用记录 - 流程单审批驳回通知";
        String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，您申请的费用记录审批已被驳回：</p></div>" +
                "<div><p style='text-indent: 2em'>费用单号：" + costMigrateVO.getCostNumber() + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批意见：" + (costMigrateVO.getProcessComments() == null ? "无" : costMigrateVO.getProcessComments()) + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
                "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 机会信息管理 - 费用信息 " +
                "<a href='" + webSitUrl + "/?m=crm&p=salesManage&me=costMigrate'>进入</a></p></div>" +
                "<div><p style='text-indent: 2em'>谢谢！</p></div>" +
                "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(user.getEmail(), null, titel, msg, token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(costMigrateVO.getBusinessId(), costMigrateVO.getLastUpdateTime(), costMigrateVO.getPrincipal(), 1, Constants.COSTRECORD_TASK_TYPE, 0, token));
//        costMigrateVO.setAuditState(3);
        costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
        approvalService.insertApprovalLog(costMigrateVO.getBusinessId(), "驳回", "费用记录审批", costMigrateVO.getProcessComments());
        return approvalService.approvalRejection(null, costMigrateVO.getBusinessId());
    }

    @Override
    public Boolean approveCostMigrate(SalesAuditVO auditVO, String token) {
        //报销迁移
        FeeMainVO vo = new FeeMainVO();
        vo.setChanceId(auditVO.getSalesRelationId());
        vo.setProjectId(auditVO.getSalesMigrateId());
        reimburseService.updateProjectIdByChanceId(vo, token);
//        if (Objects.equals(responseAPI.getCode(), "200") || Objects.equals(responseAPI.getMessage(), "该机会id无报销数据")) {
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
        List<SysUserEntity> userIList = dictionaryService.queryCcUserIdsByCode("costMigrate");
        String copyForUserEmails = getCostCopyEmail(userIList);
        String transpondEmails = transpondEmailService.selectTranspondEmailStr(auditVO.getBusinessId());
        if (!transpondEmails.isEmpty()) {
            copyForUserEmails = copyForUserEmails + "," + transpondEmails;
        }
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(auditVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        workFlowService.approvalProcessByBusinessId(activitiVO);
        //发送邮件
        SysUserEntity user = feginService.searchUserInfoByIds(opportunityVO.getOwner(), token).getResult();
        String titel = "【系统通知】费用迁移 - 流程单审批通过通知";
        String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，您申请的费用迁移审批已经通过：</p></div>" +
                "<div><p style='text-indent: 2em'>机会单号：" + opportunityVO.getOpportunityNumber() + "</p></div>" +
                "<div><p style='text-indent: 2em'>机会名称：" + opportunityVO.getOpportunityTheme() + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
                "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 机会信息管理 - 机会信息 " +
                "<a href='" + webSitUrl + "/?m=crm&p=salesManage&me=salesOpportunity'>进入</a></p></div>" +
                "<div><p style='text-indent: 2em'>谢谢！</p></div>" +
                "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        String finalCopyForUserEmails = copyForUserEmails;
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(user.getEmail(), finalCopyForUserEmails, titel, msg, token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), auditVO.getLastUpdateTime(), opportunityVO.getOwner(), 1, Constants.COSTMIGRATE_TASK_TYPE, 0, token));
        //费用迁移成功，更改费用记录信息
        SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
        costMigrateVO.setOpportunityId(auditVO.getSalesRelationId());
        costMigrateVO.setProjectManageId(auditVO.getSalesMigrateId());
        costMigrateVO.setMigrateState(1);
//        costMigrateVO.setLastUpdateBy(AuthUtils.getUserId());
//        costMigrateVO.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
        costMigrateMapper.updateCostOfProject(costMigrateVO);

        //机会采购绑定项目ID
        purchaseOrdeMapper.updatePurchaseProjectIdByOpId(auditVO.getSalesMigrateId(), auditVO.getSalesRelationId());

        //费用迁移成功，更改机会点迁移状态
        opportunityVO.setMigrateState(1);
        salesOpportunityMapper.updateByPrimaryKeySelective(opportunityVO);
        auditMapper.updateByPrimaryKeySelective(auditVO);
        approvalService.insertApprovalLog(auditVO.getBusinessId(), "通过", "费用迁移审批", auditVO.getProcessComments());
        return approvalService.approved(null, auditVO.getBusinessId());
//        }
//        return false;
    }

    @Override
    public Boolean rejectionCostMigrate(SalesAuditVO auditVO, String token) {
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
//        List<SysUserEntity> userIList = dictionaryService.queryCcUserIdsByCode("costMigrate");
//        String copyForUserEmails = getCostCopyEmail(userIList);
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ApprovalVO approvalVO = approvalService.queryApprovalByAppID(auditVO.getBusinessId());
        activitiVO.setBusinessId(approvalVO.getBusinessId());
        workFlowService.approvalProcessByBusinessId(activitiVO);
        //发送邮件
        SysUserEntity user = feginService.searchUserInfoByIds(opportunityVO.getOwner(), token).getResult();
        String titel = "【系统通知】费用迁移 - 流程单审批驳回通知";
        String msg = "<div><p>" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，您申请的费用迁移审批已被驳回：</p></div>" +
                "<div><p style='text-indent: 2em'>机会单号：" + opportunityVO.getOpportunityNumber() + "</p></div>" +
                "<div><p style='text-indent: 2em'>机会名称：" + opportunityVO.getOpportunityTheme() + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批意见：" + (auditVO.getProcessComments() == null ? "无" : auditVO.getProcessComments()) + "</p></div>" +
                "<div><p style='text-indent: 2em'>审批时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Timestamp(System.currentTimeMillis())) + "</p></div>" +
                "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 机会信息管理 - 机会信息 " +
                "<a href='" + webSitUrl + "/?m=crm&p=salesManage&me=salesOpportunity'>进入</a></p></div>" +
                "<div><p style='text-indent: 2em'>谢谢！</p></div>" +
                "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(user.getEmail(), null, titel, msg, token));
        //调用通知接口
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(auditVO.getBusinessId(), auditVO.getLastUpdateTime(), opportunityVO.getOwner(), 1, Constants.COSTMIGRATE_TASK_TYPE, 0, token));
        //费用迁移，更改机会点迁移状态
        opportunityVO.setMigrateState(0);
        salesOpportunityMapper.updateByPrimaryKeySelective(opportunityVO);
        auditMapper.updateByPrimaryKeySelective(auditVO);
        approvalService.insertApprovalLog(auditVO.getBusinessId(), "驳回", "费用迁移审批", auditVO.getProcessComments());
        return approvalService.approvalRejection(null, auditVO.getBusinessId());
    }

    @Override
    public SalesCostMigrateVO queryCostApprovalByWorkId(Integer workId) {
        SalesCostMigrateVO costMigrateVO = costMigrateMapper.queryCostApprovalByWorkId(workId);
        costMigrateVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(workId));
        return costMigrateVO;
    }

    @Override
    public SalesAuditVO queryCostAuditByWorkId(Integer workId) {
        SalesAuditVO auditVO = auditMapper.queryAuditByWorkId(workId);
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
        auditVO.setOpportunityTheme(opportunityVO.getOpportunityTheme());
        auditVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(auditVO.getBusinessId()));
        return auditVO;
    }

    @Override
    public SalesAuditVO queryCostAuditByOpId(Integer opId) {
        List<SalesAuditVO> salesAuditVOS = auditMapper.queryAuditInfo(opId, Constants.COST_MODEL_ID);
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(opId);
        SalesAuditVO auditVO = salesAuditVOS.isEmpty() ? new SalesAuditVO() : salesAuditVOS.get(0);
        auditVO.setOpportunityTheme(opportunityVO.getOpportunityTheme());
        auditVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(auditVO.getBusinessId()));
        return auditVO;
    }

    @Override
    public Boolean verifyCost(Integer opportunityId, String token) {
        SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
        costMigrateVO.setOpportunityId(opportunityId);
        List<SalesCostMigrateVO> costMigrateVOS = costMigrateMapper.queryCostById(costMigrateVO);
        if (costMigrateVOS != null && !costMigrateVOS.isEmpty()) {
            for (SalesCostMigrateVO costVO : costMigrateVOS) {
                if (costVO.getMigrateState().equals(0)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public int deleteCostById(Integer costMigrateId) {
        return costMigrateMapper.logicDelete(costMigrateId);
    }

    @Override
    public List<SalesCostMigrateVO> queryOpFailTest(Integer opportunityId) {
        SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
        costMigrateVO.setOpportunityId(opportunityId);
        List<SalesCostMigrateVO> migrateVOS = costMigrateMapper.queryCostById(costMigrateVO);
        return migrateVOS.stream().filter(cost -> cost.getMigrateState() == 0).collect(Collectors.toList());
    }

    @Override
    public int queryOpTest(Integer opId) {
        return salesOpportunityMapper.selectByPrimaryKey(opId).getMigrateState();
    }

    @Override
    public SalesCostMigrateVO queryHistoryCostRecordByApprovalId(Integer workId) {
        SalesCostMigrateVO costMigrateVO = costMigrateMapper.queryHistoryCostRecordByApprovalId(workId);
        costMigrateVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(workId));
        return costMigrateVO;
    }

    @Override
    public SalesAuditVO queryHistoryCostMigrateByApprovalId(Integer workId) {
        SalesAuditVO auditVO = auditMapper.queryHistoryAuditInfoByApprovalId(workId);
        if (Objects.isNull(auditVO)) {
            return queryCostAuditByWorkId(workId);
        }
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
        auditVO.setOpportunityTheme(opportunityVO.getOpportunityTheme());
        auditVO.setSenderList(transpondEmailService.queryTranspondByApprovalId(auditVO.getBusinessId()));
        return auditVO;
    }

    @Override
    public List<SalesOpportunityVO> selectAllOpInfo(SalesOpportunityVO opportunityVO) {
        return salesOpportunityMapper.selectAllOpInfo(opportunityVO);
    }

    @Override
    public Boolean testOpById(Integer opId) {
        SalesOpportunityVO op = salesOpportunityMapper.selectByPrimaryKey(opId);
        return (op.getAuditState() == 0 || op.getAuditState() == 1 || op.getOpportunityState() != 1 || op.getMigrateState() != 0);
    }

    @Override
    public PageUtil<SalesAuditVO> queryCostAudit(IPage<SalesAuditVO> page, SalesAuditVO auditVO, List<SysUserEntity> userList, String token) {
        if (auditVO.getOrderByProp() != null) {
            auditVO.setOrderByProp(StringUtils.camelToUnderline(auditVO.getOrderByProp()));
        }
        IPage<SalesAuditVO> iPage = auditMapper.queryCmAudit(page, auditVO, userList);
        return new PageUtil<>(iPage);
    }

    @Override
    public PageUtil<SalesAuditVO> queryCostAuditInfo(IPage<SalesAuditVO> page, SalesAuditVO auditVO, List<SysUserEntity> userList, String token) {
        if (auditVO.getOrderByProp() != null) {
            auditVO.setOrderByProp(StringUtils.camelToUnderline(auditVO.getOrderByProp()));
        }
        IPage<SalesAuditVO> iPage = auditMapper.queryCmAuditInfo(page, auditVO);
        return new PageUtil<>(iPage);
    }

    private Map getUserNameById(JSONObject jsonObject) {
        List<Map> dataDictionaryArray = (List) jsonObject.get("result");
        Map<Integer, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (Map item : dataDictionaryArray) {
                map.put((Integer) item.get("userId"), (String) item.get("loginName"));
            }
            return map;
        }
        return null;
    }

    private Map getUserAccountById(JSONObject jsonObject) {
        List<Map> dataDictionaryArray = (List) jsonObject.get("result");
        Map<Integer, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (Map item : dataDictionaryArray) {
                map.put((Integer) item.get("userId"), (String) item.get("account"));
            }
            return map;
        }
        return null;
    }

    private Map getCRMDictionaryNameByCode(String itemCode, Map listMap) {
//        LinkedHashMap linkedHashMap = (LinkedHashMap) listMap.get("result");
        List<DictionaryLookupItemVO> dataDictionaryArray = (List) listMap.get(itemCode);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(dataDictionaryArray)) {
            for (DictionaryLookupItemVO item : dataDictionaryArray) {
                map.put(item.getItemCode(), item.getItemName());
            }
            return map;
        }
        return null;
    }

    public void costRecordWithdrawal(ApprovalVO approval, String token) {
        SalesCostMigrateVO costMigrateVO = costMigrateMapper.queryCostApprovalByWorkId(approval.getApprovalId());
        costMigrateMapper.updateByPrimaryKeySelective(costMigrateVO);
    }

    public void costMigrateWithdrawal(ApprovalVO approval, String token) {
        SalesAuditVO auditVO = auditMapper.queryAuditByWorkId(approval.getApprovalId());
        //费用迁移撤回，更改费用记录信息
        SalesCostMigrateVO costMigrateVO = new SalesCostMigrateVO();
        costMigrateVO.setOpportunityId(auditVO.getSalesRelationId());
//        costMigrateVO.setProjectManageId(auditVO.getSalesMigrateId());
        costMigrateVO.setMigrateState(0);
//        costMigrateVO.setLastUpdateBy(AuthUtils.getUserId());
//        costMigrateVO.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
        costMigrateMapper.updateCostOfProject(costMigrateVO);
        //费用迁移撤回，更改机会点迁移状态
        SalesOpportunityVO opportunityVO = salesOpportunityMapper.selectByPrimaryKey(auditVO.getSalesRelationId());
        opportunityVO.setMigrateState(0);
        salesOpportunityMapper.updateByPrimaryKeySelective(opportunityVO);
        auditMapper.updateByPrimaryKeySelective(auditVO);
    }

}
